#include <bits/stdc++.h>

using namespace std;

template <typename T>
struct heap {
	int k;
	vector <T> a;

	heap(int k) : k(k) {
        a.reserve(10000000);
	}

	void sift_up(int v) {
        if (v == 0) {
            return;
        }
		int p = (v - 1) / k;
		if (a[p] > a[v]) {
			swap(a[p], a[v]);
			sift_up(p);
		}
	}

	void sift_down(int v) {
		int best = v;
		for (int i = v * k + 1; i <= v * k + k && i < a.size(); ++i) {
			if (a[i] < a[best]) {
				best = i;
			}
		}
		if (best == v) {
			return;
		}
		swap(a[v], a[best]);
		sift_down(best);
	}

	void insert(T x) {
		a.push_back(x);
		sift_up(a.size() - 1);
	}

	void extract_min() {
		swap(a[0], a.back());
		a.pop_back();
		if (!a.empty())
			sift_down(0);
	}

	T get_min() {
		return a[0];
	}

	bool empty() {
		return a.empty();
	}
};

const int INF = (int)1e9;

int main() {
    //freopen("input.txt", "r", stdin);
	int n;
	cin >> n;
	vector <vector <pair <int, int> > > g(n);
	for (int i = 0; i < n; ++i) {
		int m;
		cin >> m;
		for (int j = 0; j < m; ++j) {
            int x, y;
			cin >> x >> y;
			--y;
            g[i].push_back({y, x});
		}
	}
	vector <pair <int, int> > ans;
	int ans_len = -1;
	for (int v = 0; v < n; ++v) {
		vector <int> d(n, INF);
		heap <pair <int, int> > h(2);
		d[v] = 0;
		h.insert({d[v], v});
		while (!h.empty()) {
			int u = h.get_min().second, D = h.get_min().first;
			h.extract_min();
			if (D != d[u]) {
				continue;
			}
			for (auto e: g[u]) {
				if (d[e.first] > d[u] + e.second) {
					d[e.first] = d[u] + e.second;
					h.insert({d[e.first], e.first});
				}
			}
		}
		int len = 0;
		for (int i = 0; i < n; ++i) {
			if (d[i] != INF) {
				len = max(len, d[i]);
			}
		}
		if (ans_len > len) {
			continue;
		}
		if (ans_len < len) {
			ans.clear();
			ans_len = len;
		}
		if (ans_len == len) {
			for (int i = 0; i < n; ++i) {
				if (d[i] == len) {
					ans.push_back({v, i});
				}
			}
		}
	}
	cout << ans_len << endl;
	for (auto x: ans) {
		cout << x.first + 1 << ' ' << x.second + 1 << endl;
	}
	return 0;
}